const express = require('express')
// 数据库操作
const query = require('./db')
// 引入body-parser
const bodyPaser = require('body-parser')
// 引入path模块
const path = require('path')
// fs模块
const fs = require('fs')
// 引入jwt
const jwt = require('jsonwebtoken')

// 引入token验证
const checkTokenLogin = require('./middleware/checkLogin')

// 实例化一个http对象
const app = express()
// 监听服务
app.listen(3000)

// 中间件中注册body-parser
// 接受请求头 Content-Type:application/x-form-urlencodeed
app.use(bodyPaser.urlencoded({extended: false}))
// 接受请求头 Content-Type:application/json
app.use(bodyPaser.json())
// 文件上传 multipart/form-data  npm i -S multer

// 得到加密秘钥 同步读取文件中内容
const SECRET = fs.readFileSync(path.join(__dirname, '.env'), 'utf8').replace("\n", '')

/**
 * 用户登录
 * 请求uri /v1/api/login
 * 请求方式 post
 * 返回值 json
 */
app.post('/v1/api/login', async (req, res) => {

  // 得到账号和密码
  let {username, password} = req.body
  // 查询数据表中是否有对应的账号和密码
  let sql = `select * from users where username='${username}' and password='${password}'`
  // 执行查询 如果查询得到结果返回数组对象，查询账号和密码不存在，返回空数据
  let data = await query(sql)

  // 账号或密码不存在
  if (data.length == 0) {
    return res.status(401).send({
      code: 1000,
      msg: '账号或密码有误'
    })
  }

  // 当前时间  md5(账号+密码+随机字符串)  + token  后端发给前端
  // 当前时间   md5字符串  + token  前端发给后端  => 后端 判断ip白名单

  // 登录账号和密码成功的  保持用户的登录状态
  // 传统前后不分离  session来保持  请求界面和程序在一起不分开是同源没有不同源的情况
  // 前后端分离的，前台和后台不在同一个服务器或不在同一个域名 不同源，session将无法保存用户状态
  // 针对于前后端分离，提出解决方案：
  // 在后端接口中登录成功后，生成一个token(加密一个字符串，可以解密) 把此字符串发给前端，前端存储起来，在后续操作中都要在请求头信息中
  // 携带此token值  (token：作用保存用户登录状态)
  // 生成token node中提供一个jsonwebtoken(jwt)第3方模块 它可以帮助我们生成一个token值 加密和解密
  // jwt模块，有一个生成的秘钥字符串，此字符串是自定义，一般不要对外人告诉
  // 参数1：用于加密字符串，解密的，为后续验证所用
  // 以id+账号为进行加密
  // 参数2：加密的秘钥  混淆码
  let token = jwt.sign({
    id: data[0].id,
    username: data[0].username
  }, SECRET)


  res.send({
    code: 0,
    msg: '登录成功',
    data: {
      token
    }
  })
})


/**
 * 用户列表
 * 请求uri /v1/api/users
 * 请求方式 get
 * 返回值 json
 */
app.get('/v1/api/users', checkTokenLogin, async (req, res) => {
  let sql = "select * from users"
  let data = await query(sql)
  res.send({
    code: 0,
    msg: '成功',
    data: {
      users: data
    }
  })
})





